package com.dailyblue.java.boot.security.project.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dailyblue.java.boot.security.project.bean.Powers;
import com.dailyblue.java.boot.security.project.bean.SecurityUser;
import com.dailyblue.java.boot.security.project.bean.Users;
import com.dailyblue.java.boot.security.project.mapper.PowersMapper;
import com.dailyblue.java.boot.security.project.mapper.UsersMapper;
import com.dailyblue.java.boot.security.project.service.UsersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
@Slf4j
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements UsersService, UserDetailsService {
    @Resource
    private UsersMapper usersMapper;
    @Resource
    private PowersMapper powersMapper;
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        QueryWrapper<Users> wrapper = new QueryWrapper<>();
        wrapper.eq("username", username);
        Users user = usersMapper.selectOne(wrapper);

        if (user == null) {
            throw new UsernameNotFoundException("用户名没有找到！");
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        // 获取到当前用户的权限
        Set<Powers> userPowers = powersMapper.findAllPowerByUserId(user.getId());
        log.info("用户的权限是:{}", userPowers);
        // 获取当前用户角色的权限
        Set<Powers> rolePowers = powersMapper.findAllPowerByRoleId(user.getRoleId());
        log.info("用户所拥有的角色权限是:{}", rolePowers);
        // 合并
        Set<Powers> allPowers = new HashSet<>();
        allPowers.addAll(userPowers);
        allPowers.addAll(rolePowers);
        log.info("总的权限是：{}", allPowers);
        String[] array = new String[allPowers.size()];
        int i = 0;
        for (Powers p : allPowers) {
            array[i++] = p.getUrl();
        }
        List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList(array);
        ValueOperations<String, String> value = stringRedisTemplate.opsForValue();
        value.set("powers:" + user.getId(), JSONArray.toJSONString(authorities));

        UserDetails userDetails = new SecurityUser(user, authorities);
        return userDetails;
    }
}
